package com.gict.antifraudback.controller.web.article;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gict.antifraudback.entity.*;
import com.gict.antifraudback.exception.BusinessException;
import com.gict.antifraudback.exception.MyException;
import com.gict.antifraudback.result.ResultEnum;
import com.gict.antifraudback.result.ResultView;
import com.gict.antifraudback.service.*;
import com.gict.antifraudback.utils.UserThreadLocal;
import com.gict.antifraudback.vo.ArticleVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ThinkPad
 */
@RestController
@Slf4j
@RequestMapping("/wapi/article")
public class ArticleController {

    @Autowired
    private ArticleService articleService;
    @Autowired
    private ArticleTagsService articleTagsService;
    @Autowired
    private MenuService menuService;
    @Autowired
    private UserService userService;
    @Autowired
    private QuestionService questionService;

    @GetMapping("/getList")
    public ResultView getList(ArticleVo articleVo) {
        LambdaQueryWrapper<Article> wrapper = Wrappers.lambdaQuery();
        wrapper.like(!ObjectUtils.isEmpty(articleVo.getArticleTitle()), Article::getArticleTitle, articleVo.getArticleTitle());
        wrapper.ne(Article::getStatus, 3); // 不查询回收的文章
        wrapper.eq(articleVo.getType() != null, Article::getType, articleVo.getType());
        wrapper.eq(articleVo.getUserId() != null, Article::getUserId, articleVo.getUserId());
        wrapper.eq(articleVo.getMenuId() != null, Article::getMenuId, articleVo.getMenuId());
        wrapper.like(!ObjectUtils.isEmpty(articleVo.getArticleTitle()), Article::getArticleTitle, articleVo.getArticleTitle());
        IPage<Article> page = articleService.page(new Page<>(articleVo.getCurrent(), articleVo.getPageSize()), wrapper);
        List<Article> records = page.getRecords();
        setArticleParam(records);
        return ResultView.ok(page);
    }

    private void setArticleParam(List<Article> records) {
        if (!records.isEmpty()) {
            // 设置菜单名称
            List<Integer> menuIds = records.stream().map(Article::getMenuId).collect(Collectors.toList());
            Collection<Menu> menus = menuService.listByIds(menuIds);
            if (!menus.isEmpty()) {
                Map<Integer, Menu> menuMap = menus.stream().collect(Collectors.toMap(Menu::getId, a -> a, (a, b) -> a));
                for (Article record : records) {
                    Menu menu = menuMap.get(record.getMenuId());
                    if (menu != null) {
                        record.setMenuName(menu.getName());
                    }
                }
            }
            userService.setUserName(records);
        }
    }

    /**
     * 获取回收站文章
     *
     * @param articleVo
     * @return
     */
    @GetMapping("/getRecycleList")
    public ResultView getRecycleList(ArticleVo articleVo) {
        LambdaQueryWrapper<Article> wrapper = Wrappers.lambdaQuery();
        wrapper.like(!ObjectUtils.isEmpty(articleVo.getArticleTitle()), Article::getArticleTitle, articleVo.getArticleTitle());
        wrapper.eq(Article::getStatus, 3); // 只查询回收的文章
        wrapper.eq(articleVo.getType() != null, Article::getType, articleVo.getType());
        wrapper.eq(articleVo.getUserId() != null, Article::getUserId, articleVo.getUserId());
        wrapper.eq(articleVo.getMenuId() != null, Article::getMenuId, articleVo.getMenuId());
        wrapper.like(!ObjectUtils.isEmpty(articleVo.getArticleTitle()), Article::getArticleTitle, articleVo.getArticleTitle());
        IPage<Article> page = articleService.page(new Page<>(articleVo.getCurrent(), articleVo.getPageSize()), wrapper);
        setArticleParam(page.getRecords());
        return ResultView.ok(page);
    }

    /**
     * 回收
     */
    @GetMapping("/recycle")
    public ResultView recycle(@Valid @NotNull Integer id) {
        Article article = articleService.getById(id);
        if (article == null) {
            throw new MyException("文章不存在");
        }
        article.setStatus(3);// 回收
        articleService.updateById(article);
        return ResultView.ok(article);
    }

    /**
     * 还原
     */
    @GetMapping("/restore")
    public ResultView restore(@Valid @NotNull Integer id) {
        Article article = articleService.getById(id);
        if (article == null) {
            throw new MyException("文章不存在");
        }
        article.setStatus(1);// 显示
        articleService.updateById(article);
        return ResultView.ok(article);
    }

    /**
     * 私密
     */
    @GetMapping("/privacy")
    public ResultView privacy(@Valid @NotNull Integer id) {
        Article article = articleService.getById(id);
        if (article == null) {
            throw new MyException("文章不存在");
        }
        article.setStatus(2);// 私密
        articleService.updateById(article);
        return ResultView.ok(article);
    }

    @GetMapping("/get")
    public ResultView get(@Valid @NotNull Integer id) {
        Article article = articleService.getById(id);
        if (article == null) {
            throw new MyException("文章不存在");
        }
        List<ArticleTags> articleTags = articleTagsService.listByArticleId(article.getId());
        if (!CollectionUtils.isEmpty(articleTags)){
            article.setTags(articleTags.stream().map(ArticleTags::getTagId).collect(Collectors.toList()));
        }
        // 需要查询题目
        if (article.getContentType() == 2){
            article.setQuestions(questionService.listQuestionByArticleId(article.getId()));
        }
        return ResultView.ok(article);
    }

    @PostMapping("/delete")
    public ResultView delete(@RequestBody ArrayList<Integer> ids) {
        log.info("articleVo:{}", ids);
        for (Integer id : ids) {
            articleService.removeById(id);
        }
        return ResultView.okMsg("删除成功");
    }

    @PostMapping("/add")
    @Transactional
    public ResultView add(@Valid @RequestBody Article article) {
        this.createBefore(article);
        articleService.save(article);
        this.createAfter(article);
        return ResultView.ok();
    }

    private void createBefore(Article article) {
        if (article.getContentType() == 0) {
            if (ObjectUtils.isEmpty(article.getArticleContent())) {
                throw new BusinessException("创建文章内容不能为空！");
            }
        } else if (article.getContentType() == 1) {
            if (ObjectUtils.isEmpty(article.getVideoPath())) {
                throw new BusinessException("创建视频路径不能为空！");
            }
        } else if (article.getContentType() == 2) {
            questionService.checkParam(article.getQuestions());
        }

        article.setUserId(UserThreadLocal.get().getId());
        article.setUserName(UserThreadLocal.get().getName());
        List<Integer> tags = article.getTags();
        if (CollectionUtils.isEmpty(tags)) {
            throw new MyException("标签不能为空!");
        }
        // 修改需要删除
        if (article.getId() != null) {
            // 标签
            LambdaQueryWrapper<ArticleTags> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(ArticleTags::getArticleId, article.getId());
            // 先删除旧的标签
            articleTagsService.remove(wrapper);
            // 题目
            questionService.removeQuestionAndOptionByArticleId(article.getId());
        }
    }

    private void createAfter(Article article) {
//        保存标签关联
        List<ArticleTags> articleTagsList = new ArrayList<>();
        for (Integer tag : article.getTags()) {
            ArticleTags articleTags = new ArticleTags();
            articleTags.setTagId(tag);
            articleTags.setArticleId(article.getId());
            articleTagsList.add(articleTags);
        }
        articleTagsService.saveBatch(articleTagsList);
//        保存题目
        if (article.getContentType() == 2) {
            List<Question> questions = article.getQuestions();
            for (Question question : questions) {
                question.setArticleId(article.getId());
            }
            questionService.createQuestions(questions);
        }
    }

    @PostMapping("/update")
    public ResultView update(@RequestBody @Valid Article article) {
        Article update = articleService.getById(article.getId());
        if (update == null) {
            return ResultView.error(ResultEnum.CODE_2, "数据不存在！");
        }
        this.createBefore(article);
        articleService.updateById(article);
        this.createAfter(article);
        return ResultView.ok();
    }
}
